// SDL2_17 [Touch Events].nova using namespace lib.emscripten; using namespace lib.math; using namespace lib.sdl2; class TouchEvents { private static SDL_Window window; private static SDL_Renderer renderer; private static bool runFlag = true; // Viewport and Square properties private static int SCREEN_WIDTH = 800; private static int SCREEN_HEIGHT = 600; private static float zoomLevel = 1.0f; private static float BASE_SQUARE_SIZE = 200.0f; public static void main( String[] args ) { Stream.writeLine( "SDL2_17 [Touch Events].nova" ); // Disable the emscripten full-screen controls. Emscripten.disableControls( ); // Setup SDL. SDL2.SDL_Init( SDL2.SDL_INIT_VIDEO ); window = SDL2.SDL_CreateWindow( "Cross-Platform Zoom Test", SDL2.SDL_WINDOWPOS_CENTERED, SDL2.SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL2.SDL_WINDOW_SHOWN ); // Check for a null reference. if ( window == null ) { // Output an error message. Stream.writeLine( "Failed to create window: " + SDL2.SDL_GetError( ) ); // Abort the application. return; } renderer = SDL2.SDL_CreateRenderer( window, -1, SDL2.SDL_RENDERER_ACCELERATED | SDL2.SDL_RENDERER_PRESENTVSYNC ); // Dual-purpose main loop setup. if ( Emscripten.isActive( ) ) { // Initialize our native JavaScript trackpad/mouse listener. Emscripten.initNativeZoomListener( ); int simulate_infinite_loop = 1; int fps = -1; Emscripten.setMainLoop( mainLoop, fps, simulate_infinite_loop ); } else { do { mainLoop( ); } while ( runFlag ); } // Cleanup SDL2.SDL_DestroyRenderer( renderer ); SDL2.SDL_DestroyWindow( window ); SDL2.SDL_Quit( ); } public static void mainLoop( ) { // --- 1. BROWSER MOUSE WHEEL (Polled from JS Runtime) --- if ( Emscripten.isActive( ) ) { float zoomDelta = Emscripten.getNativeZoomDelta( ); // Stream.writeLine( "zoomLevel = " + Float.toString( zoomLevel ) ); // Stream.writeLine( "zoomDelta = " + Float.toString( zoomDelta ) ); if ( zoomDelta != 0.0f ) { zoomLevel += zoomDelta; } // Stream.writeLine( "zoomLevel (after update) = " + Float.toString( zoomLevel ) ); } SDL_Event e = SDL2.SDL_PollEvent( ); if ( e != null ) { if ( e.id == SDL2.SDL_QUIT ) { runFlag = false; } // --- 2. DESKTOP MOUSE WHEEL (Standard SDL) --- else if ( e.id == SDL2.SDL_MOUSEWHEEL ) { if ( !Emscripten.isActive( ) ) { SDL_MouseWheelEvent mwEvent = (SDL_MouseWheelEvent)e; zoomLevel += (float)mwEvent.y * 0.1f; } } // --- 3. HYBRID FILTERING (Windows Surface) --- // SDL mouse motion event. else if ( e.id == SDL2.SDL_MOUSEMOTION ) { SDL_MouseMotionEvent mmEvent = (SDL_MouseMotionEvent)e; if ( mmEvent.which == SDL2.SDL_TOUCH_MOUSEID ) { // Ignore synthetic touch event. } } // SDL mouse button event. else if ( e.id == SDL2.SDL_MOUSEBUTTONDOWN || e.id == SDL2.SDL_MOUSEBUTTONUP ) { SDL_MouseButtonEvent mbEvent = (SDL_MouseButtonEvent)e; if ( mbEvent.which == SDL2.SDL_TOUCH_MOUSEID ) { // Ignore synthetic touch event. } } // --- 4. PINCH TO ZOOM (Android, iOS, Surface Touch) --- else if ( e.id == SDL2.SDL_MULTIGESTURE ) { // Stream.writeLine( "e.id == SDL2.SDL_MULTIGESTURE" ); SDL_MultiGestureEvent mgEvent = (SDL_MultiGestureEvent)e; zoomLevel += mgEvent.dDist * 5.0f; } } // Clamp zoom level zoomLevel = Math.max( 0.1f, Math.min( zoomLevel, 3.0f ) ); // --- RENDERING --- SDL2.SDL_SetRenderDrawColor( renderer, 30, 30, 30, 255 ); SDL2.SDL_RenderClear( renderer ); float currentSize = BASE_SQUARE_SIZE * zoomLevel; int w = (int)currentSize; int h = (int)currentSize; int x = ( SCREEN_WIDTH - w ) / 2; int y = ( SCREEN_HEIGHT - h ) / 2; SDL_Rect squareRect = new SDL_Rect( x, y, w, h ); SDL2.SDL_SetRenderDrawColor( renderer, 0, 255, 100, 255 ); SDL2.SDL_RenderFillRect( renderer, squareRect ); SDL2.SDL_RenderPresent( renderer ); } }